package com.chaoyue.orders.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chaoyue.base.exception.ChaoYuePlusException;
import com.chaoyue.base.utils.IdWorkerUtils;
import com.chaoyue.base.utils.QRCodeUtil;
import com.chaoyue.messagesdk.model.po.MqMessage;
import com.chaoyue.messagesdk.service.MqMessageService;
import com.chaoyue.orders.beans.dto.AddOrderDto;
import com.chaoyue.orders.beans.dto.PayRecordDto;
import com.chaoyue.orders.beans.dto.PayStatusDto;
import com.chaoyue.orders.beans.po.CyOrders;
import com.chaoyue.orders.beans.po.CyOrdersGoods;
import com.chaoyue.orders.beans.po.CyPayRecord;
import com.chaoyue.orders.config.AlipayConfig;
import com.chaoyue.orders.config.PayNotifyConfig;
import com.chaoyue.orders.mapper.CyOrdersGoodsMapper;
import com.chaoyue.orders.mapper.CyOrdersMapper;
import com.chaoyue.orders.mapper.CyPayRecordMapper;

import com.chaoyue.orders.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author whr
 * @version 1.0
 * @description: 订单处理实现类
 * @date 2023/6/2 17:06
 */
@SuppressWarnings({"all"})
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private CyOrdersMapper ordersMapper;
    @Autowired
    private CyPayRecordMapper payRecordMapper;
    @Autowired
    private CyOrdersGoodsMapper ordersGoodsMapper;
    @Value("${pay.qrcodeurl}")
    private String qrcodeurl;
    @Value("${pay.alipay.APP_ID}")
    String APP_ID;
    @Value("${pay.alipay.APP_PRIVATE_KEY}")
    String APP_PRIVATE_KEY;
    @Value("${pay.alipay.ALIPAY_PUBLIC_KEY}")
    String ALIPAY_PUBLIC_KEY;
    @Autowired
    private OrderService current;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    MqMessageService mqMessageService;

    @Transactional
    @Override
    public PayRecordDto createOrder(String userId, AddOrderDto addOrderDto) {

        //创建订单
        CyOrders orders = saveOrders(userId, addOrderDto);
        //插入支付记录
        CyPayRecord payRecord = createPayRecord(orders);

        //生成二维码
        String qrCode = "";
        String url = String.format(qrcodeurl, payRecord.getPayNo());
        try {
            qrCode = QRCodeUtil.createQRCode(url, 200, 200);
        } catch (IOException e) {
            e.printStackTrace();
            ChaoYuePlusException.cast("生成支付二维码失败");
        }
        ;
        PayRecordDto payRecordDto = new PayRecordDto();
        BeanUtils.copyProperties(payRecord, payRecordDto);
        qrCode = "";
        payRecordDto.setQrcode(qrCode);
        return payRecordDto;

    }

    @Override
    public CyPayRecord getPayRecordByPayno(String payNo) {
        LambdaQueryWrapper<CyPayRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(!StringUtils.isEmpty(payNo), CyPayRecord::getPayNo, payNo);
        return payRecordMapper.selectOne(queryWrapper);
    }

    @Transactional
    @Override
    public PayRecordDto queryPayResult(String payNo) {
        //从数据库查询
        CyPayRecord payRecordByPayno = getPayRecordByPayno(payNo);
        if (payRecordByPayno == null) {
            ChaoYuePlusException.cast("支付记录不存在");
        }
        if (payRecordByPayno.getStatus().equals("601002")) {
            PayRecordDto payRecordDto = new PayRecordDto();
            BeanUtils.copyProperties(payRecordByPayno, payRecordDto);
            return payRecordDto;
        }
        //从支付宝查询
        PayStatusDto payStatusDto = queryPayResultFromAlipay(payNo);
        //保存支付结果
        current.saveAliPayStatus(payStatusDto);
        payRecordByPayno = getPayRecordByPayno(payNo);
        PayRecordDto payRecordDto = new PayRecordDto();
        BeanUtils.copyProperties(payRecordByPayno, payRecordDto);
        return payRecordDto;
    }

    @Transactional
    @Override
    public void saveAliPayStatus(PayStatusDto payStatusDto) {
        String payNo = payStatusDto.getOut_trade_no();
        CyPayRecord payRecordByPayno = getPayRecordByPayno(payNo);
        if (payRecordByPayno == null) {
            ChaoYuePlusException.cast("该支付记录不存在");
        }
        String status = payRecordByPayno.getStatus();
        Long orderId = payRecordByPayno.getOrderId();
        CyOrders orders = ordersMapper.selectById(orderId);
        if (orders == null) {
            ChaoYuePlusException.cast("该支付记录所关联的订单不存在");
        }
        if (orders.getStatus().equals("600002")) {
            ChaoYuePlusException.cast("该订单已支付");
        }
        if (status.equals("601002")) {
            ChaoYuePlusException.cast("该支付记录已支付");
        }
        String trade_status = payStatusDto.getTrade_status();
        if (trade_status.equals("TRADE_SUCCESS")) {
            //更新订单表信息
            orders.setStatus("600002");
            ordersMapper.updateById(orders);
            //更新支付记录表
            payRecordByPayno.setOutPayChannel("Alipay");
            payRecordByPayno.setPaySuccessTime(LocalDateTime.now());
            payRecordByPayno.setStatus("601002");
            payRecordByPayno.setOutPayNo(payStatusDto.getTrade_no());
            payRecordMapper.updateById(payRecordByPayno);
        }
        //发送支付状态
        MqMessage mqMessage = mqMessageService.addMessage("payresult_notify",orders.getOutBusinessId(), orders.getOrderType(), null);
        notifyPayResult(mqMessage);
    }

    @Override
    public void notifyPayResult(MqMessage message) {
        String jsonString = JSON.toJSONString(message);
        Message build = MessageBuilder.withBody(jsonString.getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT).build();
        Long id = message.getId();
        CorrelationData correlationData = new CorrelationData(id.toString());
        correlationData.getFuture().addCallback(result -> {
            //发送成功
            if (result.isAck()) {
                log.debug("发送消息成功,{}", jsonString);
                //从消息表中删除消息
                mqMessageService.completed(id);
            } else {
                log.debug("消息发送失败 id{},失败原因{}", correlationData.getId(), result.getReason());
            }
        }, ex -> {
            log.debug("发送消息出现异常,id{},异常原因{}", id, ex.getMessage());
        });
        rabbitTemplate.convertAndSend(PayNotifyConfig.PAYNOTIFY_EXCHANGE_FANOUT, "", build, correlationData);
    }

    /**
     * @Description: 支付宝查询支付状态
     * @Author: whr
     * @Date: 2024/5/26 20:41
     * @Param:
     * @Return:
            */
    public PayStatusDto queryPayResultFromAlipay(String payNo) {
        // AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        // AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        // JSONObject bizContent = new JSONObject();
        // bizContent.put("out_trade_no", payNo);
        // request.setBizContent(bizContent.toString());
        // AlipayTradeQueryResponse response = null;
        // try {
        //     response = alipayClient.execute(request);
        //     if (!response.isSuccess()) {
        //         ChaoYuePlusException.cast("请求支付查询查询失败");
        //     }
        // } catch (AlipayApiException e) {
        //     log.debug("请求支付信息查询失败", e.toString(), e);
        //     ChaoYuePlusException.cast("请求支付信息查询失败");
        // }
        // //获取支付结果
        // String resultJson = response.getBody();
        // //转map
        // Map resultMap = JSON.parseObject(resultJson, Map.class);
        // Map alipay_trade_query_response = (Map) resultMap.get("alipay_trade_query_response");
        // //支付结果
        // String trade_status = (String) alipay_trade_query_response.get("trade_status");
        // String total_amount = (String) alipay_trade_query_response.get("total_amount");
        // String trade_no = (String) alipay_trade_query_response.get("trade_no");

        PayStatusDto payStatusDto = new PayStatusDto();
        payStatusDto.setApp_id(APP_ID);
        payStatusDto.setOut_trade_no(payNo);
        payStatusDto.setTotal_amount("1");
        payStatusDto.setTrade_no("123");
        payStatusDto.setTrade_status("TRADE_SUCCESS");
        return payStatusDto;
    }

    public CyOrders saveOrders(String userId, AddOrderDto addOrderDto) {
        //查询订单是否已存在

        String outBusinessId = addOrderDto.getOutBusinessId();
        CyOrders order = getOrderByBusinessId(outBusinessId);
        if (order != null) {
            return order;
        }
        //新增订单
        order = new CyOrders();
        long orderId = IdWorkerUtils.getInstance().nextId();
        order.setId(orderId);
        order.setCreateDate(LocalDateTime.now());
        order.setOrderDescrip(addOrderDto.getOrderDescrip());
        order.setOrderName(addOrderDto.getOrderName());
        order.setOrderType(addOrderDto.getOrderType());
        order.setTotalPrice(addOrderDto.getTotalPrice());
        order.setUserId(userId);
        order.setOrderDetail(addOrderDto.getOrderDetail());
        order.setStatus("600001");//订单状态为未支付
        order.setOutBusinessId(outBusinessId);
        int insert = ordersMapper.insert(order);
        if (insert <= 0) {
            ChaoYuePlusException.cast("下单失败");
        }
        //获取商品详情
        String orderDetail = addOrderDto.getOrderDetail();
        List<CyOrdersGoods> ordersGoods = JSON.parseArray(orderDetail, CyOrdersGoods.class);
        //插入商品信息表
        ordersGoods.forEach(goods -> {
            CyOrdersGoods xcOrdersGoods = new CyOrdersGoods();
            BeanUtils.copyProperties(goods, xcOrdersGoods);
            xcOrdersGoods.setOrderId(orderId);
            ordersGoodsMapper.insert(xcOrdersGoods);
        });
        return order;
    }

    public CyPayRecord createPayRecord(CyOrders orders) {
        if (orders == null) {
            ChaoYuePlusException.cast("订单不存在");
        }
        if ("600002".equals(orders.getStatus())) {
            ChaoYuePlusException.cast("订单已支付");
        }
        CyPayRecord payRecord = new CyPayRecord();
        long payNo = IdWorkerUtils.getInstance().nextId();
        payRecord.setOrderId(orders.getId());
        payRecord.setOrderName(orders.getOrderName());
        payRecord.setPayNo(payNo);
        payRecord.setTotalPrice(orders.getTotalPrice());
        payRecord.setCreateDate(LocalDateTime.now());
        payRecord.setUserId(orders.getUserId());
        payRecord.setCurrency("CNY");//币种
        payRecord.setStatus("601001");//未支付
        payRecordMapper.insert(payRecord);
        return payRecord;
    }

    public CyOrders getOrderByBusinessId(String outBusinessId) {
        LambdaQueryWrapper<CyOrders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(outBusinessId != null, CyOrders::getOutBusinessId, outBusinessId);
        return ordersMapper.selectOne(queryWrapper);
    }
}
